/**
 * Copyright (c) 2019-2029, wwww.kiwipeach.cn (liuburu@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package open.kiwipeach.autoconfigure.shiro.filter;

import cn.kiwipeach.blog.exception.BlogException;
import cn.kiwipeach.blog.utils.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import open.kiwipeach.autoconfigure.shiro.token.AccessToken;
import open.kiwipeach.autoconfigure.web.utils.JwtTokenUtil;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.cache.Cache;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 描述：jwt拦截过滤器
 *
 * @author kiwipeach
 * @since 2.0
 */
@Slf4j
public class ShiroJwtFIlter extends FormAuthenticationFilter {


    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws UnauthorizedException {
        // 判断请求的请求头是否带上 "token"
        if (((HttpServletRequest) request).getHeader("token") != null) {
            // 如果存在，则进入 executeLogin 方法执行登入，检查 token 是否正确
            executeLogin(request, response);
        }else{
            // 如果请求头不存在 Token，用户可能是记住我访问或者是直接不带token的进行访问
            Subject subject = getSubject(request, response);
            if (null != subject.getPrincipals()) {
                subject.logout();
            }
        }
        return true;
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader("token");
        if (!StringUtils.isEmpty(token) && JwtTokenUtil.verify(token)) {
            AccessToken decodeAccessToken = JwtTokenUtil.decode(token);
            org.springframework.cache.CacheManager cacheManager = SpringUtil.getBean(org.springframework.cache.CacheManager.class);
            Cache accessTokenCache = cacheManager.getCache("ACCESS_TOKEN");
            String key = String.format("%s::%s", decodeAccessToken.getId(), decodeAccessToken.getRefreshToken());
            if (accessTokenCache.get(key) == null) {
                throw new BlogException("-ACCESS_TOKEN", "当前用户访问token已经失效");
            }
            getSubject(request, response).login(decodeAccessToken);
        }
        return true;
    }
}
